package com.lej.core.upload

import android.content.Context
import android.net.Uri
import android.os.Environment
import android.util.Log
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.lej.core.utils.MMKVUtils
import com.lej.core.utils.extention.toJson
import com.qiniu.android.common.FixedZone
import com.qiniu.android.storage.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.suspendCancellableCoroutine
import java.io.File
import kotlin.collections.ArrayList
import kotlin.coroutines.resume


object QiNiuFileUtils {
    private var uploadManager: UploadManager? = null
    private const val UPLOAD_FILE_URL = "upload_file_url"

    /**
     * 假如失败重试3次
     */
    suspend fun tryUploadUri(
        context: Context,
        uri: Uri,
        token: String,
        handler: UpProgressHandler? = null
    ): String? {
        var times = 0
        while (times++ < 3) {
            delay(times * 1000L)
            val result = uploadUri(context, uri, token, handler)
            if (result != null) {
                return result
            }
        }
        return null
    }

    /**
     * 上传文件
     */
    suspend fun uploadUri(
        context: Context,
        uri: Uri,
        token: String,
        handler: UpProgressHandler? = null
    ): String? {
        try {
            uploadManager ?: init(context)
        } catch (e: Exception) {
            Log.i("qiniu", e.message ?: "qiniu generator error")
            return null
        }
        return suspendCancellableCoroutine { continuation ->
            uploadManager!!.put(
                uri, context.contentResolver, "${uri.path}",
                token, { key, info, _ ->
                    if (info.isOK) {
                        setDownloadFile(true, uri.toString())
                    } else {
                        setDownloadFile(false, uri.toString())
                    }
                    continuation.resume(if (info.isOK) key else null)
                }, UploadOptions(
                    null, null, false,
                    handler, null
                )
            )
        }
    }


    private fun init(context: Context) {
        val dirPath: String = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)!!.path
        val recorder: Recorder = FileRecorder(dirPath)
        val generator = object : KeyGenerator {
            override fun gen(key: String?, file: File?): String {
                Log.d(
                    "cjq-generator_file",
                    key + "_._" + file?.length() + file?.name
                )
                return key + "_._" + file?.length()
            }

            override fun gen(key: String?, sourceId: String?): String {
                Log.d(
                    "cjq-generator_sourceId",
                    key + "_._" + sourceId
                )
                return key + "_._" + sourceId
            }
        }
        val config = Configuration.Builder()
            .connectTimeout(30)           // 链接超时。默认10秒
            .useHttps(true)
            .useConcurrentResumeUpload(true)
            .concurrentTaskCount(3)// 是否使用https上传域名
            .responseTimeout(60)          // 服务器响应超时。默认60秒
            .recorder(recorder)           // recorder分片上传时，已上传片记录器。默认null
            .recorder(recorder, generator)   // keyGen 分片上传时，生成标识符，用于片记录器区分是那个文件的上传记录
            .zone(FixedZone.zone0)        // 设置区域，不指定会自动选择。指定不同区域的上传域名、备用域名、备用IP。
            .build()
        uploadManager = UploadManager(config)
    }


    private fun setDownloadFile(success: Boolean, url: String) {
        val fileUrl = MMKVUtils.getInstance().getString(UPLOAD_FILE_URL)
        var fileList =
            Gson().fromJson<ArrayList<String>>(fileUrl, object : TypeToken<List<String>>() {}.type)
        fileList = fileList ?: ArrayList()
        if (success) {
            fileList.remove(url)
            MMKVUtils.getInstance().put(UPLOAD_FILE_URL, fileList.toJson())
        } else {
            takeIf { fileList.contains(url) }
                .apply {
                    fileList.add(url)
                    MMKVUtils.getInstance().put(UPLOAD_FILE_URL, fileList.toJson())
                }
        }
    }

    //    suspend fun upload(
//        context: Context,
//        url: String,
//        token: String,
//        handler: UpProgressHandler? = null
//    )
//            : String? {
//        try {
//            uploadManager ?: init(context)
//        } catch (e: Exception) {
//            Log.i("qiniu", e.message ?: "qiniu generator error")
//            return null
//        }
//
//        return suspendCancellableCoroutine { continuation ->
//            uploadManager!!.put(
//                url,
//                getFileName(url),
//                token,
//                { key: String?, info: ResponseInfo, res: JSONObject? ->
//                    //res包含hash、key等信息，具体字段取决于上传策略的设置
//                    Log.i("qiniu", if (info.isOK) "Upload Success" else "Upload Fail")
//                    Log.i("qiniu", "$key,\r\n $info,\r\n $res")
//                    if (info.isOK) {
//                        takeIf { Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q }.apply {
//                            val file = File(url)
//                            if (file.exists()) file.delete()
//                        }
//                        setDownloadFile(true, url)
//                    } else {
//                        setDownloadFile(false, url)
//                    }
//                    continuation.resume(if (info.isOK) key else null)
//                },
//                UploadOptions(null, null, false, handler, null)
//            )
//        }
//    }

//    private fun getFileName(url: String): String {
//        return if (url.contains("/") && url.indexOf("/") != url.length - 1) {
//            url.substring(url.lastIndexOf("/") + 1)
//        } else {
//            url
//        }
//    }

}
